import fs from 'fs';
import path from 'path';
import { execSync } from 'child_process';
import express from 'express';
import cron from 'node-cron';

// 配置部分
const config = {
    projectPath: 'C:\\Users\\li\\Desktop\\项目\\zaixianjiaoyi\\server',
    giteeRepo: 'https://gitee.com/liyucheng369/test.git',
    branch: 'main',
    logFile: './modification_log.json',
    port: 3000,
    cronSchedule: '* * * * *',
    gitUserName: 'liyucheng369',
    gitUserEmail: '823976085@qq.com'
};



// 修改方法集合
const modificationMethods = [
    (functionCode, functionName) => {
        const newParam = `String newParam${Math.floor(Math.random() * 100)}`;
        return functionCode.replace(/(public|private|protected)?\s*(static)?\s*[\w<>]+\s+\w+\s*\([^)]*\)/, `$1 $2 $&, ${newParam}`);
    },
    (functionCode, functionName) => {
        // 重命名局部变量
        const vars = functionCode.match(/(\w+)\s+(\w+)\s*[=;]/g) || [];
        if (vars.length > 0) {
            const randomVar = vars[Math.floor(Math.random() * vars.length)];
            const parts = randomVar.split(/\s+/);
            if (parts.length >= 2) {
                const oldName = parts[1];
                const newName = `renamed${Math.floor(Math.random() * 100)}`;
                return functionCode.replace(new RegExp(`\\b${oldName}\\b`, 'g'), newName);
            }
        }
        return functionCode;
    },
    (functionCode, functionName) => {
        // 添加日志语句
        const lines = functionCode.split('\n');
        const insertIndex = Math.max(1, Math.floor(Math.random() * (lines.length - 1)) + 1);
        lines.splice(insertIndex, 0, `        System.out.println("${functionName} executed at " + new java.util.Date());`);
        return lines.join('\n');
    },
    (functionCode, functionName) => {
        // 添加随机注释
        const comments = [
            '// 自动生成的代码',
            '// 优化性能',
            '// 修复潜在问题',
            '// 增强功能',
            '// 代码重构'
        ];
        const randomComment = comments[Math.floor(Math.random() * comments.length)];
        return functionCode.replace(/\{/, `{\n        ${randomComment}\n`);
    }
];

// 日志系统
class Logger {
    constructor(logFile) {
        this.logFile = logFile;
        this.ensureLogFile();
    }

    ensureLogFile() {
        if (!fs.existsSync(this.logFile)) {
            fs.writeFileSync(this.logFile, JSON.stringify([], null, 2));
        }
    }

    log(operation, file, functionName, success = true, message = '') {
        const entry = {
            timestamp: new Date().toISOString(),
            operation,
            file,
            functionName,
            success,
            message
        };

        const logs = JSON.parse(fs.readFileSync(this.logFile, 'utf8'));
        logs.push(entry);
        fs.writeFileSync(this.logFile, JSON.stringify(logs, null, 2));
        console.log(`[${entry.timestamp}] ${operation} ${success ? '成功' : '失败'}: ${file} -> ${functionName} ${message}`);
    }
}

// 主功能类
class CodeModifier {
    constructor(config) {
        this.config = config;
        this.logger = new Logger(config.logFile);
        this.lastRun = null;
        this.isRunning = false;
        this.gitInitialized = false;

        this.functionPrefixes = ['process', 'handle', 'execute', 'calculate', 'validate', 'create', 'update', 'delete', 'find', 'get', 'set'];
        this.functionSuffixes = ['Manager', 'Handler', 'Service', 'Util', 'Controller', 'Helper', 'Processor', 'Worker'];

        this.commitTypes = ['运维', '开发', '修改', '功能', '优化', '更新', '修复', '测试'];
        this.commitActions = ['开发了', '添加了', '实现了', '改进了', '优化了', '完成了', '调整了', '重构了'];
    }

    execGitCommand(command, options = {}) {
        try {
            return execSync(command, {
                cwd: this.config.projectPath,
                stdio: 'pipe',
                ...options
            }).toString().trim();
        } catch (error) {
            throw new Error(`Git命令失败: ${command}\n${error.stderr?.toString() || error.message}`);
        }
    }

    async initializeGitRepository() {
        if (this.gitInitialized) return true;

        try {
            // 设置Git配置
            this.execGitCommand(`git config user.name "${this.config.gitUserName}"`);
            this.execGitCommand(`git config user.email "${this.config.gitUserEmail}"`);

            // 检查是否是Git仓库，如果不是则初始化
            try {
                this.execGitCommand('git status');
                console.log('Git仓库已存在');
            } catch {
                console.log('初始化新的Git仓库...');
                this.execGitCommand('git init');
                this.execGitCommand(`git remote add origin ${this.config.giteeRepo}`);
                
                // 创建并切换到master分支
                this.execGitCommand('git checkout -b master');
                
                // 创建初始提交
                this.execGitCommand('git add .');
                this.execGitCommand('git commit -m "初始提交" --allow-empty');
            }

            // 确保当前在master分支
            let currentBranch;
            try {
                currentBranch = this.execGitCommand('git branch --show-current');
            } catch {
                currentBranch = 'master';
            }

            if (currentBranch !== 'master') {
                try {
                    this.execGitCommand('git checkout master');
                } catch {
                    this.execGitCommand('git checkout -b master');
                }
            }

            this.gitInitialized = true;
            console.log('Git仓库初始化成功');
            return true;

        } catch (error) {
            console.error('Git初始化失败:', error.message);
            return false;
        }
    }

    findAllCodeFiles(dirPath, arrayOfFiles = []) {
        try {
            const files = fs.readdirSync(dirPath);
            
            for (const file of files) {
                const fullPath = path.join(dirPath, file);
                try {
                    const stat = fs.statSync(fullPath);
                    
                    if (stat.isDirectory()) {
                        // 跳过不需要的目录
                        if (!file.includes('node_modules') && 
                            !file.includes('.git') && 
                            !file.includes('.idea') &&
                            !file.includes('target') &&
                            !file.includes('build')) {
                            this.findAllCodeFiles(fullPath, arrayOfFiles);
                        }
                    } else if (file.endsWith('.java')) {
                        arrayOfFiles.push(fullPath);
                    }
                } catch (error) {
                    console.log(`跳过 ${fullPath}: ${error.message}`);
                }
            }
        } catch (error) {
            console.log(`读取目录错误 ${dirPath}: ${error.message}`);
        }
        return arrayOfFiles;
    }

    extractFunctions(code, fileName) {
        const functions = [];
        if (!code) return functions;

        try {
            // 改进的Java方法匹配正则表达式
            const methodRegex = /(public|private|protected|static|\s)+[\w<>\[\]]+\s+(\w+)\s*\([^)]*\)\s*\{/g;
            let match;

            while ((match = methodRegex.exec(code)) !== null) {
                const functionName = match[2];
                
                // 跳过构造函数和明显不是方法的名字
                if (!functionName || functionName === fileName.replace('.java', '') || 
                    functionName.length < 2 || functionName.match(/^[A-Z]/)) {
                    continue;
                }

                const startPos = match.index;
                let braceCount = 1;
                let endPos = startPos + match[0].length;
                
                // 查找匹配的右大括号
                while (braceCount > 0 && endPos < code.length) {
                    if (code[endPos] === '{') braceCount++;
                    if (code[endPos] === '}') braceCount--;
                    endPos++;
                }

                if (braceCount === 0) {
                    const functionCode = code.substring(startPos, endPos);
                    
                    // 确保方法代码包含至少一行逻辑（不只是声明）
                    if (functionCode.includes(';') || functionCode.includes('return') || 
                        functionCode.split('\n').length > 3) {
                        functions.push({
                            name: functionName,
                            code: functionCode,
                            start: startPos,
                            end: endPos
                        });
                    }
                }
            }

            // 如果没有找到方法，尝试更宽松的匹配
            if (functions.length === 0) {
                const relaxedRegex = /\w+\s+(\w+)\s*\([^)]*\)\s*\{/g;
                let relaxedMatch;
                
                while ((relaxedMatch = relaxedRegex.exec(code)) !== null) {
                    const functionName = relaxedMatch[1];
                    if (functionName && functionName.length > 1) {
                        functions.push({
                            name: functionName,
                            code: '// 简化的方法匹配',
                            start: 0,
                            end: 0
                        });
                    }
                }
            }

        } catch (error) {
            console.log('提取方法错误:', error.message);
        }
        
        return functions;
    }

    generateRandomFunctionName(originalName) {
        const prefix = this.functionPrefixes[Math.floor(Math.random() * this.functionPrefixes.length)];
        const suffix = this.functionSuffixes[Math.floor(Math.random() * this.functionSuffixes.length)];
        return prefix + originalName.charAt(0).toUpperCase() + originalName.slice(1) + suffix;
    }

    generateChineseCommitMessage(functionName) {
        const randomType = this.commitTypes[Math.floor(Math.random() * this.commitTypes.length)];
        const randomAction = this.commitActions[Math.floor(Math.random() * this.commitActions.length)];
        return `${randomType}: ${randomAction} ${functionName}方法`;
    }

    async modifyAndCommit() {
        if (this.isRunning) return;
        this.isRunning = true;
        this.lastRun = new Date();

        try {
            console.log('开始修改过程...');

            if (!await this.initializeGitRepository()) {
                throw new Error('Git初始化失败');
            }

            // 查找Java文件
            const codeFiles = this.findAllCodeFiles(this.config.projectPath);
            if (codeFiles.length === 0) {
                throw new Error('未找到Java文件');
            }

            console.log(`找到 ${codeFiles.length} 个Java文件`);

            // 尝试多个文件直到找到有方法的文件
            let functions = [];
            let selectedFile = '';
            let attempts = 0;
            const maxAttempts = 10;

            while (functions.length === 0 && attempts < maxAttempts) {
                selectedFile = codeFiles[Math.floor(Math.random() * codeFiles.length)];
                console.log(`检查文件: ${path.basename(selectedFile)}`);
                
                try {
                    const fileContent = fs.readFileSync(selectedFile, 'utf8');
                    functions = this.extractFunctions(fileContent, path.basename(selectedFile));
                    console.log(`在 ${path.basename(selectedFile)} 中找到 ${functions.length} 个方法`);
                } catch (error) {
                    console.log(`读取文件失败: ${selectedFile}`, error.message);
                }
                
                attempts++;
            }

            if (functions.length === 0) {
                throw new Error('未找到合适的方法');
            }

            const randomFunction = functions[Math.floor(Math.random() * functions.length)];
            const newFunctionName = this.generateRandomFunctionName(randomFunction.name);

            console.log(`选择方法: ${randomFunction.name} -> ${newFunctionName}`);

            // 选择随机修改方法
            const randomModification = modificationMethods[Math.floor(Math.random() * modificationMethods.length)];
            let modifiedFunctionCode;
            
            if (randomFunction.code !== '// 简化的方法匹配') {
                modifiedFunctionCode = randomModification(randomFunction.code, randomFunction.name);
                
                // 修改并写入文件
                const fileContent = fs.readFileSync(selectedFile, 'utf8');
                const beforeFunction = fileContent.substring(0, randomFunction.start);
                const afterFunction = fileContent.substring(randomFunction.end);
                
                const newFileContent = beforeFunction + modifiedFunctionCode + afterFunction;
                fs.writeFileSync(selectedFile, newFileContent, 'utf8');
            } else {
                // 对于简化匹配，直接在文件末尾添加新方法
                const fileContent = fs.readFileSync(selectedFile, 'utf8');
                const newMethod = `
    // 自动生成的方法
    public void ${newFunctionName}() {
        System.out.println("${newFunctionName} executed");
        // 自动添加的功能
    }
`;
                fs.writeFileSync(selectedFile, fileContent + newMethod, 'utf8');
            }

            // 生成中文提交信息
            const commitMessage = this.generateChineseCommitMessage(newFunctionName);

            // Git 操作
            this.execGitCommand('git add .');
            this.execGitCommand(`git commit -m "${commitMessage}"`);

            // 推送到远程
            try {
                this.execGitCommand('git push origin master');
            } catch (error) {
                console.log('推送失败，尝试强制推送:', error.message);
                this.execGitCommand('git push -f origin master');
            }

            this.logger.log('修改', path.basename(selectedFile), randomFunction.name, true, `修改了方法 ${newFunctionName}`);
            console.log('修改完成! 提交信息:', commitMessage);

        } catch (error) {
            this.logger.log('执行', '系统', 'N/A', false, error.message);
            console.error('错误:', error.message);
        } finally {
            this.isRunning = false;
        }
    }

    startScheduler() {
        console.log('启动调度器...');
        cron.schedule(this.config.cronSchedule, () => {
            console.log('定时任务触发...');
            this.modifyAndCommit();
        });
        
        console.log(`监控服务器运行在 http://localhost:${this.config.port}`);
        
        // 立即执行一次
        setTimeout(() => this.modifyAndCommit(), 2000);
    }
}

// 主程序
const modifier = new CodeModifier(config);
modifier.startScheduler();